package com.bkgy.controller.technology.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.commom.model.QueryDTO;
import com.bkgy.commom.model.Temp;
import com.bkgy.controller.planking.dao.TBProfit1870Dao;
import com.bkgy.controller.planking.dao.TBProfit1870ResDao;
import com.bkgy.controller.planking.entity.TbProfit1870;
import com.bkgy.controller.planking.entity.TbProfit1870Res;
import com.bkgy.controller.technology.entity.Cgl1870ProcessDatas;
import com.bkgy.controller.technology.entity.ExcelTech;
import com.bkgy.controller.technology.entity.TTech;
import com.bkgy.controller.technology.entity.TTechParam;
import com.bkgy.controller.technology.entity.dto.*;
import com.bkgy.controller.technology.mapper.ITechMapper;
import com.bkgy.controller.technology.mapper.ITechParamMapper;
import com.bkgy.controller.technology.service.ICalProcessService;
import com.bkgy.controller.technology.service.ICgl1870ProcessService;
import com.bkgy.controller.technology.service.ITcm2280ProcessService;
import com.bkgy.controller.technology.service.ITechService;
import com.bkgy.controller.tpdol3data.service.ITPdoL3Cal1630Service;
import com.bkgy.controller.tpdol3data.service.ITPdoL3Cal2150Service;
import com.bkgy.controller.tpdol3data.service.ITPdoL3Cgl1870Service;
import com.bkgy.controller.tpdol3data.service.ITPdoL3Tcm2280Service;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import com.bkgy.util.ExcelUtilsPOI;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class TechServiceImpl extends ServiceImpl<ITechMapper, TTech> implements ITechService {
    private final TBProfit1870ResDao profitResDao;
    private final ITechParamMapper techParamDao;
    private final TBProfit1870Dao tbProfitDao;
    private final ITcm2280ProcessService tcm2280Service;
    private final ICalProcessService calService;
    private final ICgl1870ProcessService cgl1870Service;
    private final ITPdoL3Tcm2280Service pdo2280Service;
    private final ITPdoL3Cal2150Service pdo2150Service;
    private final ITPdoL3Cal1630Service pdo1630Service;
    private final ITPdoL3Cgl1870Service pdo1870Service;

    @Override
    public ResultData<String> saveTech(TTech tech) {
        save(tech);
        return ResultData.ResultDataSuccess("success");
    }

    @Override
    public ResultData<String> updateTech(TTech tech) {
        updateById(tech);
        return ResultData.ResultDataSuccess("success");
    }

    @Override
    public ResultData<Page<TTech>> pageTech(QueryDTO<TechQueryDto> queryDTO) {
        TechQueryDto dto = queryDTO.getDto();
        LambdaQueryWrapper<TTech> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(dto.getStartDate()))
            wrapper.ge(TTech::getDatetime, dto.getStartDate());
        if (StringUtils.isNotEmpty(dto.getEndDate()))
            wrapper.lt(TTech::getDatetime, dto.getEndDate());
        if (StringUtils.isNotEmpty(dto.getLineCode())) {
            wrapper.eq(TTech::getLineCode, dto.getLineCode());
        }
        Page<TTech> p = new Page<>(queryDTO.getPage().getPageIndex(), queryDTO.getPage().getPageSize());
        Page<TTech> result = page(p, wrapper);
        return ResultData.ResultDataSuccess(result.getRecords(), (int) result.getTotal());
    }

    @Override
    public ResultData<String> loadRoll(String lineCode) {
        int rollNum = 20;
        List<JSONObject> list = new ArrayList<>();
        //酸轧查出口卷号，其它查入口卷号
        List<Temp> dataList = new ArrayList<>();
        if ("tcm2280".equals(lineCode)) {
            dataList = pdo2280Service.selectPage(rollNum);
        } else if ("cal2150".equals(lineCode)) {
            dataList = pdo2150Service.selectPage(rollNum);
        } else if ("cal1630".equals(lineCode)) {
            dataList = pdo1630Service.selectPage(rollNum);
        } else if ("cgl1870".equals(lineCode)) {
            dataList = pdo1870Service.selectPage(rollNum);
        }
        for (Temp t : dataList) {
            JSONObject obj = new JSONObject();
            obj.put("value", t.getK());
            obj.put("label", t.getK1() + " " + t.getK() + " " + t.getK2());
            list.add(obj);
        }
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData<String> deleteTech(Integer indocno) {
        removeById(indocno);
        return ResultData.ResultDataSuccess("success");
    }

    @Override
    public void exportXlsx(TechQueryDto techReq, HttpServletResponse res) {
        LambdaQueryWrapper<TTech> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(techReq.getLineCode())) {
            wrapper.eq(TTech::getLineCode, techReq.getLineCode());
        }
        if (StringUtils.isNotEmpty(techReq.getStartDate())) {
            wrapper.ge(TTech::getDatetime, techReq.getStartDate());
        }
        if (StringUtils.isNotEmpty(techReq.getEndDate())) {
            wrapper.le(TTech::getDatetime, techReq.getEndDate());
        }
        List<TTech> dbList = list(wrapper);

        List<ExcelTech> list = new ArrayList<>();
        for (TTech obj : dbList) {
            ExcelTech excel = new ExcelTech();
            BeanUtils.copyProperties(obj, excel);
            list.add(excel);
        }
        try {
            Map<String, Object> dataMap = new HashMap();
            dataMap.put("data", list);
            File file = ResourceUtils.getFile("classpath:exceltemplate\\工艺参数列表.xlsx");
            TemplateExportParams templ = new TemplateExportParams(file.getPath(), false);
            Workbook workbook = ExcelExportUtil.exportExcel(templ, dataMap);
            ExcelUtilsPOI.exportExcel("工艺参数列表", res, workbook);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResultData<Tech6CharRes> selectTechFit(TechChartDtoReq tc) {
        Tech6CharRes obj = new Tech6CharRes();
        obj.setExtIdArr(new ArrayList<>());
        obj.setCredateArr(new ArrayList<>());
        obj.setSprayCondActArr(new ArrayList<>());
        obj.setBrushCondActArr(new ArrayList<>());
        obj.setSprayTempArr(new ArrayList<>());
        obj.setBrushTempArr(new ArrayList<>());
        obj.setElecTempArr(new ArrayList<>());
        obj.setRinseTempArr(new ArrayList<>());
        obj.setElecCondActArr(new ArrayList<>());
        obj.setRinseCondActArr(new ArrayList<>());
        obj.setSpmLiquidConcArr(new ArrayList<>());
        obj.setAirKnifeDisTopArr(new ArrayList<>());
        obj.setAirKnifeDisBtmArr(new ArrayList<>());
        obj.setAirKnifeHighTopArr(new ArrayList<>());
        obj.setAirKnifeHighBtmArr(new ArrayList<>());
        obj.setGiZnpotTempArr(new ArrayList<>());
        obj.setGaZnpotTempArr(new ArrayList<>());
        obj.setSpmElongActArr(new ArrayList<>());

        LambdaQueryWrapper<Cgl1870ProcessDatas> w = cgl1870Service.build1870Wrapper(tc);
        w.select(Cgl1870ProcessDatas::getExtid,
                Cgl1870ProcessDatas::getEndtime,
                Cgl1870ProcessDatas::getSprayCondActAvg,
                Cgl1870ProcessDatas::getBrushCondActAvg,
                Cgl1870ProcessDatas::getSprayTempAvg,
                Cgl1870ProcessDatas::getBrushTempAvg,
                Cgl1870ProcessDatas::getElecTempAvg,
                Cgl1870ProcessDatas::getRinseTempAvg,
                Cgl1870ProcessDatas::getElecCondActAvg,
                Cgl1870ProcessDatas::getRinseCondActAvg,
                Cgl1870ProcessDatas::getSpmLiquidConcAvg,
                Cgl1870ProcessDatas::getAirKnifeDisTopAvg,
                Cgl1870ProcessDatas::getAirKnifeDisBtmAvg,
                Cgl1870ProcessDatas::getAirKnifeHighTopAvg,
                Cgl1870ProcessDatas::getAirKnifeHighBtmAvg,
                Cgl1870ProcessDatas::getGiZnpotTempAvg,
                Cgl1870ProcessDatas::getGaZnpotTempAvg,
                Cgl1870ProcessDatas::getSpmElongActAvg,

                Cgl1870ProcessDatas::getSprayCondActJudge,
                Cgl1870ProcessDatas::getBrushCondActJudge,
                Cgl1870ProcessDatas::getSprayTempJudge,
                Cgl1870ProcessDatas::getBrushTempJudge,
                Cgl1870ProcessDatas::getElecTempJudge,
                Cgl1870ProcessDatas::getRinseTempJudge,
                Cgl1870ProcessDatas::getElecCondActJudge,
                Cgl1870ProcessDatas::getRinseCondActJudge,
                Cgl1870ProcessDatas::getSpmLiquidConcJudge,
                Cgl1870ProcessDatas::getAirKnifeDisTopJudge,
                Cgl1870ProcessDatas::getAirKnifeDisBtmJudge,
                Cgl1870ProcessDatas::getAirKnifeHighTopJudge,
                Cgl1870ProcessDatas::getAirKnifeHighBtmJudge,
                Cgl1870ProcessDatas::getGiZnpotTempJudge,
                Cgl1870ProcessDatas::getGaZnpotTempJudge,
                Cgl1870ProcessDatas::getSpmElongActJudge
        );

        List<Cgl1870ProcessDatas> cgl1870List = cgl1870Service.list(w);
        for (int i = 0; i < cgl1870List.size(); i++) {
            Cgl1870ProcessDatas p = cgl1870List.get(i);
            obj.getExtIdArr().add(p.getExtid());
            obj.getCredateArr().add(p.getEndtime());
            obj.getSprayCondActArr().add(p.getSprayCondActAvg());
            obj.getBrushCondActArr().add(p.getBrushCondActAvg());
            obj.getSprayTempArr().add(p.getSprayTempAvg());
            obj.getBrushTempArr().add(p.getBrushTempAvg());
            obj.getElecTempArr().add(p.getElecTempAvg());
            obj.getRinseTempArr().add(p.getRinseTempAvg());
            obj.getElecCondActArr().add(p.getElecCondActAvg());
            obj.getRinseCondActArr().add(p.getRinseCondActAvg());
            obj.getSpmLiquidConcArr().add(p.getSpmLiquidConcAvg());
            BigDecimal v1 = p.getAirKnifeDisTopAvg();
            if (v1 != null)
                v1 = v1.divide(BigDecimal.valueOf(100));
            obj.getAirKnifeDisTopArr().add(v1);
            BigDecimal v2 = p.getAirKnifeDisBtmAvg();
            if (v2 != null)
                v2 = v2.divide(BigDecimal.valueOf(100));
            obj.getAirKnifeDisBtmArr().add(v2);
            obj.getAirKnifeHighTopArr().add(p.getAirKnifeHighTopAvg());
            obj.getAirKnifeHighBtmArr().add(p.getAirKnifeHighBtmAvg());
            obj.getGiZnpotTempArr().add(p.getGiZnpotTempAvg());
            obj.getGaZnpotTempArr().add(p.getGaZnpotTempAvg());
            obj.getSpmElongActArr().add(p.getSpmElongActAvg());
        }

        //上下限数据
        LambdaQueryWrapper<TTechParam> wrapper = new LambdaQueryWrapper<>();
        Integer[] arr = new Integer[]{1, 3, 4, 5, 6, 11, 14, 15, 16, 17};
        wrapper.select(TTechParam::getProNo, TTechParam::getBaseValue, TTechParam::getBaseValueOffset)
                .in(TTechParam::getProNo, arr);
        List<TTechParam> paramList = techParamDao.selectList(wrapper);
        for (TTechParam p : paramList) {
            //碱洗温度
            if ("1".equals(p.getProNo())) {
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal a = p.getBaseValue().subtract(BigDecimal.valueOf(v));
                BigDecimal b = p.getBaseValue().add(BigDecimal.valueOf(v));
                obj.setSprayTempA(a);
                obj.setSprayTempB(b);
                obj.setBrushTempA(a);
                obj.setBrushTempB(b);
                obj.setElecTempA(a);
                obj.setElecTempB(b);
            } else if ("3".equals(p.getProNo())) {
                //漂洗温度
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal a = p.getBaseValue().subtract(BigDecimal.valueOf(v));
                BigDecimal b = p.getBaseValue().add(BigDecimal.valueOf(v));
                obj.setRinseTempA(a);
                obj.setRinseTempB(b);
            } else if ("4".equals(p.getProNo())) {
                //碱洗电导率
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal a = BigDecimal.valueOf(v);
                obj.setSprayCondActA(a);
                obj.setSprayCondActB(null);
                obj.setBrushCondActA(a);
                obj.setBrushCondActB(null);
            } else if ("5".equals(p.getProNo())) {
                //电解清洗电导率
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal a = BigDecimal.valueOf(v);
                obj.setElecCondActA(a);
                obj.setElecCondActB(null);
            } else if ("6".equals(p.getProNo())) {
                //漂洗电导率
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal b = BigDecimal.valueOf(v);
                obj.setRinseCondActA(null);
                obj.setRinseCondActB(b);
            } else if ("11".equals(p.getProNo())) {
                //锌液温度
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal a = p.getBaseValue().subtract(BigDecimal.valueOf(v));
                BigDecimal b = p.getBaseValue().add(BigDecimal.valueOf(v));
                obj.setGiZnpotTempA(a);
                obj.setGiZnpotTempB(b);
                obj.setGaZnpotTempA(a);
                obj.setGaZnpotTempB(b);
            } else if ("14".equals(p.getProNo())) {
                //气刀距离
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal b = BigDecimal.valueOf(v).divide(BigDecimal.valueOf(100));
                obj.setAirKnifeDisTopA(null);
                obj.setAirKnifeDisTopB(b);
                obj.setAirKnifeDisBtmA(null);
                obj.setAirKnifeDisBtmB(b);
            } else if ("15".equals(p.getProNo())) {
                //气刀高度
                String str = p.getBaseValueOffset().substring(1);
                Integer v = Integer.parseInt(str);
                BigDecimal a = p.getBaseValue().subtract(BigDecimal.valueOf(v));
                BigDecimal b = p.getBaseValue().add(BigDecimal.valueOf(v));
                obj.setAirKnifeHighTopA(a);
                obj.setAirKnifeHighTopB(b);
                obj.setAirKnifeHighBtmA(a);
                obj.setAirKnifeHighBtmB(b);
            } else if ("16".equals(p.getProNo())) {
                //光整延伸率
                String str = p.getBaseValueOffset().substring(1);
                Double v = Double.parseDouble(str);
                BigDecimal b = BigDecimal.valueOf(v);
                obj.setSpmElongActA(null);
                obj.setSpmElongActB(b);
            } else if ("17".equals(p.getProNo())) {
                //光整液浓度
                String str = p.getBaseValueOffset().substring(1);
                BigDecimal offSet = BigDecimal.valueOf(Double.parseDouble(str));
                BigDecimal a = p.getBaseValue().subtract(offSet);
                BigDecimal b = p.getBaseValue().add(offSet);
                obj.setSpmLiquidConcA(a);
                obj.setSpmLiquidConcB(b);
            }
        }
        return ResultData.ResultDataSuccess(obj);
    }

    @Override
    public ResultData<TechListDtoRes> selectTechList(TechChartDtoReq tc) {
        List<TechListDtoRes> list = new ArrayList<>();

        //根据不同产线调用不同查询
        if ("cgl1870".equals(tc.getProdLine())) {
            list = cgl1870Service.load1870ProcessData(tc);
        } else if ("cal1630".equals(tc.getProdLine()) || "cal2150".equals(tc.getProdLine())) {
            list = calService.loadCalProcessData(tc);
        } else {
            list = tcm2280Service.load2280ProcessData(tc);
        }
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData<JSONObject> techCrewProfit() {
        JSONObject obj = new JSONObject();
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        String d = DateUtil.getDateToString(new Date(), "yyyyMMdd" + ((hour >= 8 && hour < 19) ? "08" : "19"));
        LambdaQueryWrapper<TbProfit1870Res> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TbProfit1870Res::getTimePoint, DateUtil.getDateToString(new Date(), d));
        TbProfit1870Res res = profitResDao.selectOne(wrapper);
        obj.put("estimate", res != null ? res.getSumProfit() : "0");

        LambdaQueryWrapper<TbProfit1870> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.ge(TbProfit1870::getCredate, d).orderByDesc(TbProfit1870::getCredate);
        List<TbProfit1870> list1 = tbProfitDao.selectList(wrapper2);

        List<TbProfit1870> list = new ArrayList<>();
        BigDecimal sumActi = BigDecimal.ZERO;
        for (TbProfit1870 p : list1) {
            if (p.getTonProfitTotal() != null)
                sumActi = sumActi.add(p.getTonProfitTotal());
            //挑出5个有异常的记录
            if (list.size() < 5) {
                if ((p.getPressAirExc() != null && p.getPressAirExc() == 1)
                        || (p.getSteamExc() != null && p.getSteamExc() == 1)
                        || (p.getSaltExc() != null && p.getSaltExc() == 1)
                        || (p.getGasExc() != null && p.getGasExc() == 1)
                        || (p.getFineNitrogenExc() != null && p.getFineNitrogenExc() == 1)
                        || (p.getRoughNitrogenExc() != null && p.getRoughNitrogenExc() == 1)
                        || (p.getCleanWaterExc() != null && p.getCleanWaterExc() == 1)
                        || (p.getHydrogenExc() != null && p.getHydrogenExc() == 1)
                        || (p.getPowerMountExc() != null && p.getPowerMountExc() == 1)
                        || (p.getNOilamountExc() != null && p.getNOilamountExc() == 1)
                        || (p.getZincExc() != null && p.getZincExc() == 1)) {
                    list.add(p);
                }
            }
        }
        obj.put("acti", sumActi);
        obj.put("exec", list);
        return ResultData.ResultDataSuccess(obj);
    }

    @Override
    public ResultData<TechExecDtoRes> techExecList() {
        List<TechExecDtoRes> list = new ArrayList<>();
        TechExecDtoRes o1 = new TechExecDtoRes();
        o1.setExtid("440W");
        o1.setBrandNo("1.0");
        o1.setThick(BigDecimal.valueOf(98));
        o1.setWidth(BigDecimal.valueOf(99));
        list.add(o1);
        TechExecDtoRes o2 = new TechExecDtoRes();
        o2.setExtid("440WD+Z");
        o2.setBrandNo("1.30");
        o2.setThick(BigDecimal.valueOf(98));
        o2.setWidth(BigDecimal.valueOf(98.7));
        list.add(o2);
        TechExecDtoRes o3 = new TechExecDtoRes();
        o3.setExtid("590DPD");
        o3.setBrandNo("3.90");
        o3.setThick(BigDecimal.valueOf(98));
        o3.setWidth(BigDecimal.valueOf(96.1));
        list.add(o3);
        TechExecDtoRes o4 = new TechExecDtoRes();
        o4.setExtid("B210P");
        o4.setBrandNo("1.00");
        o4.setThick(BigDecimal.valueOf(98));
        o4.setWidth(BigDecimal.valueOf(99));
        list.add(o4);
        TechExecDtoRes o5 = new TechExecDtoRes();
        o5.setExtid("B250P");
        o5.setBrandNo("0.40");
        o5.setThick(BigDecimal.valueOf(98));
        o5.setWidth(BigDecimal.valueOf(99.6));
        list.add(o5);
        TechExecDtoRes o6 = new TechExecDtoRes();
        o6.setExtid("BZT1");
        o6.setBrandNo("1.80");
        o6.setThick(BigDecimal.valueOf(98));
        o6.setWidth(BigDecimal.valueOf(98.2));
        list.add(o6);
        TechExecDtoRes o7 = new TechExecDtoRes();
        o7.setExtid("BZT2");
        o7.setBrandNo("0.20");
        o7.setThick(BigDecimal.valueOf(98));
        o7.setWidth(BigDecimal.valueOf(99.8));
        list.add(o7);

        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData<TechCrewProfitDtoRes> techCrewProfitList() {
        List<TechCrewProfitDtoRes> list = new ArrayList<>();
        TechCrewProfitDtoRes o1 = new TechCrewProfitDtoRes();
        o1.setCrew("班组1");
        o1.setSec(330);
        o1.setProfit(BigDecimal.valueOf(340));
        o1.setProfitHour(BigDecimal.valueOf(335));
        list.add(o1);
        TechCrewProfitDtoRes o2 = new TechCrewProfitDtoRes();
        o2.setCrew("班组2");
        o2.setSec(360);
        o2.setProfit(BigDecimal.valueOf(370));
        o2.setProfitHour(BigDecimal.valueOf(365));
        list.add(o2);
        TechCrewProfitDtoRes o3 = new TechCrewProfitDtoRes();
        o3.setCrew("班组3");
        o3.setSec(390);
        o3.setProfit(BigDecimal.valueOf(400));
        o3.setProfitHour(BigDecimal.valueOf(395));
        list.add(o3);
        TechCrewProfitDtoRes o4 = new TechCrewProfitDtoRes();
        o4.setCrew("班组4");
        o4.setSec(300);
        o4.setProfit(BigDecimal.valueOf(310));
        o4.setProfitHour(BigDecimal.valueOf(305));
        list.add(o4);
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData<TechBrandProfitDtoRes> techBrandProfitList() {
        List<TechBrandProfitDtoRes> list = new ArrayList<>();
        TechBrandProfitDtoRes o1 = new TechBrandProfitDtoRes();
        o1.setBrand("入口切头");
        o1.setProfitHour(BigDecimal.valueOf(1630));
        o1.setTonProfit(BigDecimal.valueOf(98));
        list.add(o1);
        TechBrandProfitDtoRes o2 = new TechBrandProfitDtoRes();
        o2.setBrand("入口切尾");
        o2.setProfitHour(BigDecimal.valueOf(410));
        o2.setTonProfit(BigDecimal.valueOf(98));
        list.add(o2);
        return ResultData.ResultDataSuccess(list, list.size());
    }
}
